import { login, logout, getInfo } from "@/api/user";
import { getToken, setToken, removeToken } from "@/utils/auth";
import {
  resetRouter,
  allAsyncRoutes,
  constantRoutes,
  anyRoute
} from "@/router";
import router from "@/router";
import {cloneDeep} from 'lodash'

// 1.封装一个过滤符合菜单权限的异步路由的函数
const filterAsyncRoutes = (allAsyncRoutes, routes) => {
  // console.log(allAsyncRoutes, "allAsyncRoutes");
  // console.log(routes, "routes");
  // 过滤出当前员工需要展示的异步路由
  return allAsyncRoutes.filter(item => {
    // item是异步路由中的每个一级路由,判断一级路由是否符合菜单权限
    if (routes.includes(item.name)) {
      // 一级路由符合再过滤二级路由---递归
      //递归的限制条件（防止栈溢出）： 有二级路由且二级路由个数大于0
      if (item.children && item.children.length > 0) {
        item.children = filterAsyncRoutes(item.children, routes);
      }
      // filter只有在内部返回true的时候才能收集到符合条件的数据
      return true;
    }
  });
};

const getDefaultState = () => {
  return {
    token: getToken(),
    name: "",
    avatar: "",

    roles: [], //角色名称的数组
    buttons: [], //按钮权限
    routes: [], //菜单权限
    resultAsyncRoutes: [], //符合菜单权限的所有动态（异步）路由
    resultAllRoutes: [] //用户的所有路由(静态，动态，任意)
  };
};

const state = getDefaultState();

const mutations = {
  RESET_USER: state => {
    Object.assign(state, getDefaultState());
  },
  SET_TOKEN: (state, token) => {
    state.token = token;
  },
  // SET_NAME: (state, name) => {
  //   state.name = name
  // },
  // SET_AVATAR: (state, avatar) => {
  //   state.avatar = avatar
  // },
  SET_USER: (state, userInfo) => {
    state.name = userInfo.name; //用户名
    state.avatar = userInfo.avatar; //用户头像
    state.roles = userInfo.roles; //用户角色
    state.buttons = userInfo.buttons; //按钮权限
    state.routes = userInfo.routes; //菜单权限
  },
  // 设置符合权限的异步路由
  SET_RESULTASYNCROUTES: (state, asyncRoutes) => {
    state.resultAsyncRoutes = asyncRoutes;
    // 将动态路由合并到静态路由中
    state.resultAllRoutes = constantRoutes.concat(
      state.resultAsyncRoutes,
      anyRoute
    );
    // 给路由器添加新的路由,将用户最终路由添加到路由器
    router.addRoutes(state.resultAllRoutes);
  }
};

const actions = {
  // user login
  login({ commit }, userInfo) {
    const { username, password } = userInfo;
    return new Promise((resolve, reject) => {
      login({ username: username.trim(), password: password })
        .then(response => {
          const { data } = response;
          commit("SET_TOKEN", data.token);
          setToken(data.token);
          resolve();
        })
        .catch(error => {
          reject(error);
        });
    });
  },

  // get user info
  getInfo({ commit, state }) {
    return new Promise((resolve, reject) => {
      getInfo()
        .then(response => {
          const { data } = response;

          if (!data) {
            return reject("Verification failed, please Login again.");
          }
          const asyncRoutes = filterAsyncRoutes(cloneDeep(allAsyncRoutes), data.routes);
          // console.log(re, "filterAsyncRoutes");
          commit("SET_USER", data);
          commit("SET_RESULTASYNCROUTES", asyncRoutes);
          resolve(data);
        })
        .catch(error => {
          reject(error);
        });
    });
  },

  // user logout
  logout({ commit, state }) {
    return new Promise((resolve, reject) => {
      logout(state.token)
        .then(() => {
          removeToken(); // must remove  token  first
          resetRouter();
          commit("RESET_USER");
          resolve();
        })
        .catch(error => {
          reject(error);
        });
    });
  },

  // remove token
  resetToken({ commit }) {
    return new Promise(resolve => {
      removeToken(); // must remove  token  first
      commit("RESET_USER");
      resolve();
    });
  }
};

export default {
  namespaced: true,
  state,
  mutations,
  actions
};
